bitkeeper revision 1.253 (3ede2580BOyG2X8oTsgB7U5xY-U9XQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 4 Jun 2003 16:59:44 +0000 (16:59 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 4 Jun 2003 16:59:44 +0000 (16:59 +0000)
processor.h, setup.c, process.c, ioport.c, head.S:
  Yet another IOPL fix -- tested this time :-)

xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/head.S
xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/ioport.c
xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/process.c
xenolinux-2.4.21-pre4-sparse/arch/xeno/kernel/setup.c
xenolinux-2.4.21-pre4-sparse/include/asm-xeno/processor.h

index 6278ececb35784ba61baa63bba55735b8b26c262..a89fd8eda49a7f527dd2eaefcfe0c09c59ad5740 100644 (file)
@@ -50,11 +50,8 @@ startup_32:
                 
         jmp SYMBOL_NAME(start_kernel)
 
-# Stack is 8kB. We leave 100 bytes trailer for fake 'pt_regs'.
-# This is needed so that iopl checks of the saved eflags register
-# work correctly, for example.
 ENTRY(stack_start)
-       .long SYMBOL_NAME(init_task_union)+8192-100, __KERNEL_DS
+       .long SYMBOL_NAME(init_task_union)+8192, __KERNEL_DS
 
 .org 0x1000
 ENTRY(empty_zero_page)
index b86f8ee4d5d1d42ee51f86bf7419259c4408160e..7b30b8dcf2bd03045bbb212f6635bfab099a7eef 100644 (file)
@@ -16,7 +16,7 @@ asmlinkage int sys_iopl(unsigned long unused)
 {
     struct pt_regs *regs = (struct pt_regs *)&unused;
     unsigned int new_io_pl = regs->ebx & 3;
-    unsigned int old_io_pl = (regs->eflags >> 12) & 3;
+    unsigned int old_io_pl = current->thread.io_pl;
     unsigned int new_hypercall_pl = (regs->ebx >> 2) & 3;
     unsigned int old_hypercall_pl = current->thread.hypercall_pl;
 
@@ -32,11 +32,11 @@ asmlinkage int sys_iopl(unsigned long unused)
     /* Maintain OS privileges even if user attempts to relinquish them. */
     if ( new_hypercall_pl == 0 )
         new_hypercall_pl = 1;
-    if ( (new_io_pl == 0) && !(start_info.flags & SIF_PRIVILEGED) )
+    if ( (new_io_pl == 0) && (start_info.flags & SIF_PRIVILEGED) )
         new_io_pl = 1;
 
     /* Change our version of the privilege levels. */
-    regs->eflags = (regs->eflags & 0xffffcfff) | (old_io_pl << 12);
+    current->thread.io_pl        = new_io_pl;
     current->thread.hypercall_pl = new_hypercall_pl;
 
     /* Force the change at ring 0. */
index b4e7a6cd148051b4f96f24f9c1ccee87adc5c438..6605ce2e659209ccb544a63fea640505344f235d 100644 (file)
@@ -252,6 +252,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
                 struct task_struct * p, struct pt_regs * regs)
 {
     struct pt_regs * childregs;
+    unsigned long eflags;
 
     childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
     struct_cpy(childregs, regs);
@@ -269,6 +270,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
     unlazy_fpu(current);
     struct_cpy(&p->thread.i387, &current->thread.i387);
 
+
+    __asm__ __volatile__ ( "pushfl; popl %0" : "=r" (eflags) : );
+    p->thread.io_pl = (eflags >> 12) & 3;
+
     /* We're careful with hypercall privileges. Don't allow inheritance. */
     p->thread.hypercall_pl = 1;
 
@@ -368,8 +373,7 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
     queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
     /* Next call will silently fail if we are a non-privileged guest OS. */
     queue_multicall2(__HYPERVISOR_set_priv_levels,
-                     ((((struct pt_regs *)next->esp0)-1)->eflags>>12)&3,
-                     next->hypercall_pl);
+                     next->io_pl, next->hypercall_pl);
 
     /* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
     execute_multicall_list();
index 68fedf85fd6862889047729ea9e836bfa76685d5..1d34609225576422c64572e576e58d238060d71f 100644 (file)
@@ -143,7 +143,6 @@ static void __init parse_mem_cmdline (char ** cmdline_p)
 
 void __init setup_arch(char **cmdline_p)
 {
-    struct pt_regs *regs = ((struct pt_regs *)current->thread.esp0) - 1;
     unsigned long start_pfn, max_pfn, max_low_pfn;
     unsigned long bootmap_size;
     unsigned long i;
@@ -302,12 +301,12 @@ void __init setup_arch(char **cmdline_p)
 
     paging_init();
 
-    regs->eflags &= ~(3<<12);
+    current->thread.hypercall_pl = 1;
     if ( start_info.flags & SIF_PRIVILEGED ) {
+        current->thread.io_pl = 1;
         /* We are privileged guest os - should have IO privileges. */
         if( HYPERVISOR_set_priv_levels(1, 1) )
             panic("Unable to obtain IOPL, despite being SIF_PRIVILEGED");
-        regs->eflags |= 1<<12;
     }
 
     if(start_info.flags & SIF_CONSOLE)
index eb2effd3f074f6b59504872eed129a65acd83423..4fdb36ca370a545c2b9d299e78a83ec1c1670d66 100644 (file)
@@ -356,7 +356,7 @@ struct thread_struct {
        unsigned long   esp;
        unsigned long   fs;
        unsigned long   gs;
-       unsigned int    hypercall_pl;
+       unsigned int    io_pl, hypercall_pl;
 /* Hardware debugging registers */
        unsigned long   debugreg[8];  /* %%db0-7 debug registers */
 /* fault info */
@@ -370,7 +370,7 @@ struct thread_struct {
 };
 
 #define INIT_THREAD  { sizeof(init_stack) + (long) &init_stack, \
-                       0, 0, 0, 0, 1, {0}, 0, 0, 0, {0}, 0, 0, 0, 0, 0 }
+                       0, 0, 0, 0, 0, 0, {0}, 0, 0, 0, {0}, 0, 0, 0, 0, 0 }
 
 #define INIT_TSS  {                                            \
        0,0, /* back_link, __blh */                             \